// CSE571 - abstract-interpreter.cpp          
// Authors: Jonathan Wald, Guangle Fan
// Defines the interpreter used for reading commands in from the terminal.
// The interpreter is an active object that runs concurrently with the
// rest of the application.

#include <string>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>

#include "abstract-interpreter.h"
#include "async-io-svc-handler.h"
#include "game-manager.h"
#include "player-svc-handler.h"
#include "player-game.h"

using namespace std;

int AbstractInterpreter::svc (void) {
  while(true) {
    string line;
    getline(cin, line);
    istringstream iss(line);
    process_input(iss);
  }
  
  return 0;
}

void AbstractInterpreter::process_input (istream& is) {

    std::string command;
    is >> command;

    if (command == "define") {
      std::string filename;
      is >> filename;
      define(filename);
    } else if (command == "process") {
      std::string filename;
      is >> filename;
      process(filename);
    } else if (command == "current") {
      std::string label;
      is >> label;
      std::string value;
      is >> value;
      current(label, value);
    } else if (command == "play") {
      std::string game;
      is >> game;
      play(game);
    } else if (command == "dontplay") {
      std::string game;
      is >> game;
      dontplay(game);
    } else if (command == "suspend") {
      std::string game;
      is >> game;
      suspend(game);
    } else if (command == "resume") {
      std::string game;
      is >> game;
      resume(game);
    }
}

void AbstractInterpreter::process(string filename) {
  ifstream ifs(filename.c_str());
  if (!ifs.is_open()) {
    std::cout << "Could not open file for processing." << std::endl;
    return;
  }
  set<std::string>::iterator iter;
  iter = open_files.find(filename);
  if(iter != open_files.end()) {
    std::cout << "File " << filename << " already open, won't open again to "
	      << "avoid infinite recursion." << std::endl;
    return;
  } else {
    open_files.insert(filename);
  }
  string line;
  while(getline(ifs, line).good()) {
    istringstream iss(line);
    process_input(iss);
  }
  if(!line.empty()) {
    istringstream iss(line);
    process_input(iss);
  }
  open_files.erase(filename);

}
